// keyof 用来取得一个对象接口的所有key值
// keyof 关键字动态地取出某个键值对类型的key,推导出 联合类型
interface Foo {
  name: string;
  age: number;
}
type T = keyof Foo;

//in 则可以遍历枚举类型
type Keys = "a" | "b";
type Obj = {
  [p in Keys]: any;
};

// infer只能在条件类型的 extends 子句中使用,
// T extends U ? X : Y;
// infer得到的类型只能在true语句中使用, 即X中使用

// Equals
type Equals<X, Y> = (<T1>() => T1 extends X ? 1 : 2) extends (<T2>() => T2 extends Y ? 1 : 2) ? true : false;

// includes 是否包含
type myInclude<T extends readonly any[], U> = T extends [infer F, ...infer R] ? Equals<F, U> extends true ? true : myInclude<R, U> : false

type pick<T, U extends keyof T> = {
  [P in U]: T[P]
}
type omit<T, U extends keyof T> = {
  [P in keyof T as P extends U ? never : P]: T[P]
}
type omit2<T, U extends keyof T> = {
  [P in exclude<keyof T, U>]: T[P]
}

type partail<T> = {
  [P in keyof T]?: T[P]
}
type require<T> = {
  [P in keyof T]-?: T[P]
}
type readonly<T> = {
  readonly [P in keyof T]: T[P]
}

type exclude<T, U> = T extends U ? never : T
type extract<T, U> = T extends U ? T : never

type concat<T, U> = T extends unknown[] ? U extends unknown[] ? [...T, ...U] : never : never

type pop<T> = T extends [infer F, ...infer R] ? R : never
